from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.runtime import DeadlineExceededError

import simplejson as json, pickle

import models, sys

from hd_commons import *

class UploadGraphPage(webapp.RequestHandler):
    
    def get(self):
        self.response.headers['Content-Type'] = 'text/html'
        self.response.out.write("""
<form method='POST'>
  <textarea name='graph' rows='20' cols='40'></textarea><br />
  <input type='submit' value='upload' />
</form>        
""")
        
    def post(self):
        indata = self.request.get('graph')
        indata = json.loads(indata)
        stations = {}
        for station in indata['stations']:
            if not station['id']: 
                continue
            if not station['lon']:
                self.response.out.write(str(station) + '<br />\n')
                return
            stations[station['id']] = {'id': station['id'], 'lat' : float(station['lat']), 'lon' : float(station['lon']), 'name' : station['name'], 'next_stations' : {}}
        
        routes = {}
        for route in indata['routes']:
            routes[route['id']] = {
                                   'id' : route['id'], 
                                   'name' : route['name'], 
                                   'direction' : route['direction'], 
                                   'stations' : route['stations']}
            for i in xrange(len(route['stations'])-1):
                station_id = route['stations'][i]
                next_station_id = route['stations'][i+1]
                station = stations[station_id]
                if next_station_id not in station['next_stations']: station['next_stations'][next_station_id] = []
                station['next_stations'][next_station_id].append({'route' : route['id'],'station_id' : next_station_id})                                 
        
        for link in indata['links']:
            if link['to'] not in stations[link['from']]: continue
            for next_station_info in stations[link['from']][link['to']]:
                next_station_info['len'] = link['len']
                
        map = {'routes' : routes, 'stations' : stations}
        binary = pickle.dumps(map)
        dbData = models.BinaryData.get_or_insert('map')
        dbData.data = binary
        dbData.save()         
        self.response.out.write(map)        

counter = 0
MAX_PATH_LEN = 50
class Test(webapp.RequestHandler):
    def get(self):
        global counter
        counter = 0
        sys.setrecursionlimit(1000)
        
        map = get_map()
        stations = map['stations']
        start = '642'
        path = []
        have_station = {}
        try:
            def try_path(current):
                global counter
                path.append(current)
                have_station[current] = 1
                if len(
                       stations[current]
                       ['next_stations']
                       ) == 0:
                    counter += 1
                elif len(path) == MAX_PATH_LEN:
                    pass
                else:
                    for next in stations[current]['next_stations'].keys():
                        if next not in have_station:
                            try_path(next)
                del have_station[current]
                path.pop()
            try_path(start)
            self.response.out.write(str(counter))
        except DeadlineExceededError:
            self.response.out.write('timeout: ' + str(counter))
        

application = webapp.WSGIApplication([
                                      ('/admin/upload', UploadGraphPage),
                                      ('/admin/test', Test),
                                      ], debug=True)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
